package com.web.controller.api;

import com.web.config.PayConfiguration;
import com.web.dao.*;
import com.web.entity.*;
import com.web.manager.CoreManager;
import com.web.manager.jpush.SendJPushMessage;
import com.web.pay.*;
import com.xkk.utils.MapUtil;
import com.xkk.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author FDjavaone
 * @date 2017/9/1
 */
@Slf4j
@RestController
@RequestMapping("api")
public class PayController {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderGoodsMapper orderGoodsMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private PlatformMapper platformMapper;
    @Autowired
    private ProfitConfigMapper profitConfigMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private PoundageConfigMapper poundageConfigMapper;
    @Autowired
    private ConsumptionDetailMapper consumptionDetailMapper;
    @Autowired
    private PayConfiguration payConfiguration;
    @Autowired
    private RechargeRecordMapper rechargeRecordMapper;
    @Autowired
    private RegionRecordMapper regionRecordMapper;
    @Autowired
    private CoreManager coreManager;

    /**
     * 支付宝异步回调通知
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/open/ali_notify")
    public String aliNotify(HttpServletRequest request) {
        Date date = new Date();
        AliPayDto aliPayDto = new AliPayDto();
        aliPayDto.setMap(RequestUtil.getParams(request));
        if (aliPayDto.getMap() == null || aliPayDto.getMap().isEmpty()) {
            log.warn("支付宝回调解析失败->回调参数为空");
            return "";
        }
        aliPayDto.setPayAppid(payConfiguration.getAli().getAppid());
        aliPayDto.setPayUrl(payConfiguration.getAli().getUrl());
        aliPayDto.setPaySelfSecret(payConfiguration.getAli().getSelfSecret());
        aliPayDto.setPayPublicSecret(payConfiguration.getAli().getPublicSecret());
        aliPayDto.setPayPublicSecret2(payConfiguration.getAli().getPublicSecret2());
        PayResponse payResponse = AliPayManage.mg.aliValid(aliPayDto);
        if (payResponse.isOk()) {
            Map<String, String> payMap = (Map) payResponse.getParams();
            String orderNum = payMap.get("out_trade_no");
            BigDecimal totalPrice = new BigDecimal(payMap.get("total_amount"));

            Order order = orderMapper.selectByOrderNum(orderNum);
            //测试情况下
            totalPrice = order.getTotalPrice().add(order.getTipPrice());
            //trade_status 表示订单交易状态
            String trade_status = payMap.get("trade_status");
            String tradeStatus = "TRADE_SUCCESS";
            if (tradeStatus.equals(trade_status)) {
                if (order.getStatus() != 0) {
                    //订单已经回调通知排除已成功通知
                    log.info("支付宝支付" + orderNum + "重复通知支付结果！");
                    return "success";
                }
                //交易成功
                log.info("支付宝支付" + orderNum + "支付成功！");
                //消费者信息
                Member member = memberMapper.selectByPrimaryKey(order.getmId());
                //商家店铺信息
                Store store = storeMapper.selectByPrimaryKey(order.getStoreId());

                Message message1 = new Message();
                message1.setTargetName("");
                message1.setTarget(store.getmId());
                message1.setFromName("系统");
                message1.setFrom(0L);
                message1.setTitle("新订单提醒");
                message1.setContent("您有新的订单产生请及时处理，订单编号：" + orderNum);
                message1.setCreateTime(date);
                message1.setModifyTime(date);
                messageMapper.insertSelective(message1);
                SendJPushMessage.jPushByMessage(message1);
                Order update = new Order();
                update.setPayType(5);
                update.setId(order.getId());
                //对于企业订单消费者确认收货之后才去分成
                String online = "online";
                if (order.getOrderType().equals(online)) {
                    //企业订单
                    //更新订单支付状态

                    update.setStatus(1);
                    orderMapper.updateByPrimaryKeySelective(update);

                } else {
                    orderMapper.updateByPrimaryKeySelective(update);
                    //直接消费订单

                    //消费者账户信息
                    Account account = accountMapper.selectByMid(order.getmId());

                    CompanyReport companyReport = new CompanyReport();
                    companyReport.setReserve1("支付宝消费,订单编号" + orderNum);
                    companyReport.setReserve2("5");

                    //商家账户信息
                    Account merchantAccount = accountMapper.selectByMid(store.getmId());
                    //商户信息
                    Member merchant = memberMapper.selectByPrimaryKey(store.getmId());

                    Member memberUp = null;
                    if (member.getInvitedCode() != null) {
                        //用户上线
                        memberUp = memberMapper.selectMyUp(member.getInvitedCode());
                    }

                    Member merchantUp = null;
                    if (merchant.getInvitedCode() != null) {
                        //商户上线
                        merchantUp = memberMapper.selectMyUp(merchant.getInvitedCode());
                    }

                    //店铺的省市区三级代理商获取
                    RegionRecord province = regionRecordMapper.selectProvince(store.getProvince());
                    RegionRecord city = regionRecordMapper.selectProvinceAndCity(store.getProvince(), store.getCity());
                    RegionRecord region = regionRecordMapper.selectProvinceAndCityAndRegion(store.getProvince(), store.getCity(), store.getRegion());

                    //总的奖励分配
                    BigDecimal totalBonus = new BigDecimal("0");

                    //利润分配配置
                    ProfitConfig config = profitConfigMapper.selectByPrimaryKey(1L);
                    //msk卖出配置
                    PoundageConfig poundageConfig = poundageConfigMapper.selectByPrimaryKey(1L);
                    //平台账户信息
                    Platform platform = platformMapper.selectByPrimaryKey(1L);

                    synchronized (this) {

                        //核心处理方法
                        coreManager.coreOperation(order, totalPrice, totalBonus, order.getTransferPrice(), config, poundageConfig, platform, member, memberUp, account, merchant, merchantUp
                                , merchantAccount, province, city, region, date, store, companyReport);

                    }
                }


                // 推送消息
                Message message = new Message();
                message.setModifyTime(date);
                message.setCreateTime(date);
                message.setContent("尊敬的用户您使用支付宝支付订单：" + orderNum + "，" + totalPrice + " 元。成功支付！");
                message.setTitle("支付结果");
                message.setFrom(0L);
                message.setFromName("系统");
                message.setTarget(member.getId());
                message.setTargetName(member.getNickName());
                messageMapper.insertSelective(message);
                SendJPushMessage.jPushByMessage(message);

            } else if ("TRADE_FINISHED".equals(trade_status)) {
                log.info("过滤交易完成通知！");
            } else {
                log.info("支付宝支付" + orderNum + "支付失败！回退订单锁定库存，删除订单，及订单明细！");
                //支付不成功回退订单锁定库存，删除订单，及订单明细
                List<OrderGoods> orderGoods = orderGoodsMapper.selectByOrderId(order.getId());
                for (OrderGoods o : orderGoods) {
                    //回退库存
                    goodsMapper.numAdd(o.getNum(), o.getId());
                }

                orderMapper.deleteByPrimaryKeyLogic(order.getOrderNum());
                Message message = new Message();
                message.setModifyTime(date);
                message.setCreateTime(date);
                message.setContent("尊敬的用户您使用支付宝支付订单：" + orderNum + "，" + totalPrice + " 元。支付失败！");
                message.setTitle("支付结果");
                message.setFrom(0L);
                message.setFromName("系统");
                message.setTarget(order.getmId());
                message.setTargetName("");
                messageMapper.insertSelective(message);
                SendJPushMessage.jPushByMessage(message);
                return "";
            }

            return "success";
        } else {

            return "";
        }
    }


    /**
     * 微信支付回调
     */
    @RequestMapping("/open/wx_notify")
    @ResponseBody
    public String wxNotify(HttpServletRequest request) {
        String xml = "";
        try {
            xml = IOUtils.toString(request.getInputStream());
        } catch (IOException e) {
            log.warn("微信回调解析失败->{}", e.getMessage());
        }
        Map<String, String> map = MapUtil.sortAsc(MapUtil.xmlToMap(xml));
        WxPayDto wxPayDto = new WxPayDto();
        wxPayDto.setAppid(StringUtils.defaultString(map.get("appid")));
        wxPayDto.setMch_id(StringUtils.defaultString(map.get("mch_id")));
        if (!StringUtils.equals(wxPayDto.getAppid(), payConfiguration.getWx().getAppId())) {
            log.warn("wx notify error->appid不一致");
            return "";
        }
        wxPayDto.setSignKey(payConfiguration.getWx().getSignKey());
        //校验
        PayResponse payResponse = WxPayManage.mg.wxValid(wxPayDto, map);
        if (payResponse.isOk()) {
            //处理逻辑
            //获取transaction_id 交易订单号
            Date date = new Date();
            String orderNum = map.get("out_trade_no");
            BigDecimal totalPrice = new BigDecimal(map.get("total_fee"));
            String tradeStatus = map.get("result_code");
            Order order = orderMapper.selectByOrderNum(orderNum);
            //测试情况下
            totalPrice = order.getTotalPrice().add(order.getTipPrice());
            String success = "SUCCESS";
            if (success.equals(tradeStatus)) {
                //交易成功
                log.info("微信支付" + orderNum + "支付成功！");
                if (order.getStatus() != 0) {
                    //订单已经回调通知排除已成功通知
                    log.info("微信支付" + orderNum + "重复通知支付结果！");
                    return "<?xmlversion=\"1.0\"encoding=\"UTF-8\"?><xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                }

                //消费者信息
                Member member = memberMapper.selectByPrimaryKey(order.getmId());
                //商家店铺信息
                Store store = storeMapper.selectByPrimaryKey(order.getStoreId());


                Message message1 = new Message();
                message1.setTargetName("");
                message1.setTarget(store.getmId());
                message1.setFromName("系统");
                message1.setFrom(0L);
                message1.setTitle("新订单提醒");
                message1.setContent("您有新的订单产生请及时处理，订单编号：" + orderNum);
                message1.setCreateTime(date);
                message1.setModifyTime(date);
                messageMapper.insertSelective(message1);
                SendJPushMessage.jPushByMessage(message1);
                Order update = new Order();
                update.setPayType(4);
                update.setId(order.getId());
                if (order.getOrderType().equals("online")) {
                    //企业订单
                    //更新订单支付状态
                    update.setStatus(1);
                    orderMapper.updateByPrimaryKeySelective(update);
                } else {
                    orderMapper.updateByPrimaryKeySelective(update);
                    //消费者账户信息
                    Account account = accountMapper.selectByMid(order.getmId());
                    //商家账户信息
                    Account merchantAccount = accountMapper.selectByMid(store.getmId());
                    //商户信息
                    Member merchant = memberMapper.selectByPrimaryKey(store.getmId());
                    Member memberUp = null;
                    if (member.getInvitedCode() != null) {
                        //用户上线
                        memberUp = memberMapper.selectMyUp(member.getInvitedCode());
                    }
                    Member merchantUp = null;
                    if (merchant.getInvitedCode() != null) {
                        //商户上线
                        merchantUp = memberMapper.selectMyUp(merchant.getInvitedCode());
                    }
                    //店铺的省市区三级代理商获取
                    RegionRecord province = regionRecordMapper.selectProvince(store.getProvince());
                    RegionRecord city = regionRecordMapper.selectProvinceAndCity(store.getProvince(), store.getCity());
                    RegionRecord region = regionRecordMapper.selectProvinceAndCityAndRegion(store.getProvince(), store.getCity(), store.getRegion());
                    CompanyReport companyReport = new CompanyReport();
                    companyReport.setReserve1("微信消费,订单编号" + orderNum);
                    companyReport.setReserve2("4");
                    //总的奖励分配
                    BigDecimal totalBonus = new BigDecimal(0);
                    //利润分配配置
                    ProfitConfig config = profitConfigMapper.selectByPrimaryKey(1L);
                    //msk卖出配置
                    PoundageConfig poundageConfig = poundageConfigMapper.selectByPrimaryKey(1L);
                    //平台账户信息
                    Platform platform = platformMapper.selectByPrimaryKey(1L);
                    synchronized (this) {
                        //核心处理方法
                        coreManager.coreOperation(order, totalPrice, totalBonus, order.getTransferPrice(), config, poundageConfig, platform, member, memberUp, account, merchant, merchantUp
                                , merchantAccount, province, city, region, date, store, companyReport);
                    }

                }
                //boolean flag=iUserOrderService.updateOrder(orderId);
                //log.info("订单修改状态："+(flag?"成功":"失败"));
                // 推送消息
                Message message = new Message();
                message.setModifyTime(date);
                message.setCreateTime(date);
                message.setContent("尊敬的用户您使用微信支付订单：" + orderNum + "，" + totalPrice + " 元。成功支付！");
                message.setTitle("支付结果");
                message.setFrom(0L);
                message.setFromName("系统");
                message.setTarget(member.getId());
                message.setTargetName(member.getNickName());
                messageMapper.insertSelective(message);
                SendJPushMessage.jPushByMessage(message);
            } else {
                log.info("微信支付" + orderNum + "支付失败！回退订单锁定库存，删除订单，及订单明细！");
                //支付不成功回退订单锁定库存，删除订单，及订单明细
                List<OrderGoods> orderGoods = orderGoodsMapper.selectByOrderId(order.getId());
                for (OrderGoods o : orderGoods) {
                    //回退库存
                    goodsMapper.numAdd(o.getNum(), o.getId());
                }
                //作废订单
                orderMapper.deleteByPrimaryKeyLogic(order.getOrderNum());
                Message message = new Message();
                message.setModifyTime(date);
                message.setCreateTime(date);
                message.setContent("尊敬的用户您使用微信支付订单：" + orderNum + "，" + totalPrice + " 元。支付失败！");
                message.setTitle("支付结果");
                message.setFrom(0L);
                message.setFromName("系统");
                message.setTarget(order.getmId());
                message.setTargetName("");
                messageMapper.insertSelective(message);
                SendJPushMessage.jPushByMessage(message);
            }
            return "<?xmlversion=\"1.0\"encoding=\"UTF-8\"?><xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } else {

            log.warn("微信回调 处理失败->{}", payResponse.getMessage());
            return "";
        }

    }


    /**
     * 支付宝充值异步回调通知
     *
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/open/ali_notify_recharge")
    public String aliNotifyRecharge(HttpServletRequest request) {
        Date date = new Date();
        AliPayDto aliPayDto = new AliPayDto();
        aliPayDto.setMap(RequestUtil.getParams(request));
        if (aliPayDto.getMap() == null || aliPayDto.getMap().isEmpty()) {
            log.warn("支付宝回调解析失败->回调参数为空");
            return "";
        }
        aliPayDto.setPayAppid(payConfiguration.getAli().getAppid());
        aliPayDto.setPayUrl(payConfiguration.getAli().getUrl());
        aliPayDto.setPaySelfSecret(payConfiguration.getAli().getSelfSecret());
        aliPayDto.setPayPublicSecret(payConfiguration.getAli().getPublicSecret());
        aliPayDto.setPayPublicSecret2(payConfiguration.getAli().getPublicSecret2());
        PayResponse payResponse = AliPayManage.mg.aliValid(aliPayDto);
        if (payResponse.isOk()) {
            Map<String, String> payMap = (Map) payResponse.getParams();
            String orderNum = payMap.get("out_trade_no");

            RechargeRecord rechargeRecord = rechargeRecordMapper.selectByOutTradeNo(orderNum);
            //trade_status 表示订单交易状态
            String trade_status = payMap.get("trade_status");
            if ("TRADE_SUCCESS".equals(trade_status)) {
                //交易成功
                log.info("支付宝支付" + orderNum + "支付成功！");
                if (rechargeRecord.getStatus() != 0) {
                    //订单已经回调通知排除已成功通知
                    log.info("支付宝支付" + orderNum + "重复通知支付结果！");
                    return "success";
                }
                Account account = accountMapper.selectByMid(rechargeRecord.getmId());
                Member member = memberMapper.selectByPrimaryKey(account.getmId());
                accountMapper.consumptionAdd(rechargeRecord.getAmount(), account.getId());
                ConsumptionDetail consumptionDetail = new ConsumptionDetail();
                consumptionDetail.setCreateTime(date);
                consumptionDetail.setModifyTime(date);
                consumptionDetail.setaId(account.getId());
                consumptionDetail.setContent("账户充值");
                consumptionDetail.setDetail("+" + rechargeRecord.getAmount());
                consumptionDetail.setBal(accountMapper.selectByMid(account.getmId()).getConsumption().toString());
                consumptionDetail.setFromNum(orderNum);
                consumptionDetail.setName(member.getName());
                consumptionDetail.setPhone(member.getPhone());
                consumptionDetailMapper.insertSelective(consumptionDetail);

                rechargeRecord.setStatus(1);
                rechargeRecord.setModifyTime(date);
                rechargeRecordMapper.updateByPrimaryKeySelective(rechargeRecord);
            }

            return "success";
        } else {
            return "";
        }

    }


    /**
     * 微信充值支付回调
     */
    @RequestMapping("/open/wx_notify_recharge")
    @ResponseBody
    public String wxNotifyRecharge(HttpServletRequest request) {
        String xml = "";
        try {
            xml = IOUtils.toString(request.getInputStream());
        } catch (IOException e) {
            log.warn("微信回调解析失败->{}", e.getMessage());
        }
        Map<String, String> map = MapUtil.sortAsc(MapUtil.xmlToMap(xml));
        WxPayDto wxPayDto = new WxPayDto();
        wxPayDto.setAppid(StringUtils.defaultString(map.get("appid")));
        wxPayDto.setMch_id(StringUtils.defaultString(map.get("mch_id")));
        if (!StringUtils.equals(wxPayDto.getAppid(), payConfiguration.getWx().getAppId())) {
            log.warn("wx notify error->appid不一致");
            return "";
        }
        wxPayDto.setSignKey(payConfiguration.getWx().getSignKey());
        //校验
        PayResponse payResponse = WxPayManage.mg.wxValid(wxPayDto, map);
        if (payResponse.isOk()) {
            //获取transaction_id 交易订单号
            Date date = new Date();
            String orderNum = map.get("out_trade_no");
            String tradeStatus = map.get("result_code");

            //测试情况下
            if ("SUCCESS".equals(tradeStatus)) {
                //交易成功
                log.info("微信支付" + orderNum + "支付成功！");
                RechargeRecord rechargeRecord = rechargeRecordMapper.selectByOutTradeNo(orderNum);
                if (rechargeRecord.getStatus() != 0) {
                    //订单已经回调通知排除已成功通知
                    log.info("微信支付" + orderNum + "重复通知支付结果！");
                    return "<?xmlversion=\"1.0\"encoding=\"UTF-8\"?><xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                }

                Account account = accountMapper.selectByMid(rechargeRecord.getmId());
                Member member = memberMapper.selectByPrimaryKey(account.getmId());
                accountMapper.consumptionAdd(rechargeRecord.getAmount(), account.getId());
                ConsumptionDetail consumptionDetail = new ConsumptionDetail();
                consumptionDetail.setCreateTime(date);
                consumptionDetail.setModifyTime(date);
                consumptionDetail.setaId(account.getId());
                consumptionDetail.setContent("账户充值");
                consumptionDetail.setDetail("+" + rechargeRecord.getAmount());
                consumptionDetail.setBal(accountMapper.selectByMid(account.getmId()).getConsumption().toString());
                consumptionDetail.setFromNum(orderNum);
                consumptionDetail.setName(member.getName());
                consumptionDetail.setPhone(member.getPhone());

                consumptionDetailMapper.insertSelective(consumptionDetail);

                rechargeRecord.setStatus(1);
                rechargeRecord.setModifyTime(date);
                rechargeRecordMapper.updateByPrimaryKeySelective(rechargeRecord);

            }

            return "<?xmlversion=\"1.0\"encoding=\"UTF-8\"?><xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } else {
            return "";
        }
    }
}
